home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Collator.java < prev    next >
Text File  |  1998-09-22  |  19KB  |  463 lines

  1. /*
  2.  * @(#)Collator.java    1.14 98/08/19
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996-1997 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.text;
  32.  
  33. import java.io.Serializable;
  34. import java.util.Locale;
  35. import java.util.MissingResourceException;
  36. import java.util.ResourceBundle;
  37. import java.text.resources.*;
  38. import java.util.Hashtable;
  39.  
  40.  
  41. /**
  42.  * The <code>Collator</code> class performs locale-sensitive
  43.  * <code>String</code> comparison. You use this class to build
  44.  * searching and sorting routines for natural language text.
  45.  *
  46.  * <p>
  47.  * <code>Collator</code> is an abstract base class. Subclasses
  48.  * implement specific collation strategies. One subclass,
  49.  * <code>RuleBasedCollator</code>, is currently provided with
  50.  * the JDK and is applicable to a wide set of languages. Other
  51.  * subclasses may be created to handle more specialized needs.
  52.  *
  53.  * <p>
  54.  * Like other locale-sensitive classes, you can use the static
  55.  * factory method, <code>getInstance</code>, to obtain the appropriate
  56.  * <code>Collator</code> object for a given locale. You will only need
  57.  * to look at the subclasses of <code>Collator</code> if you need
  58.  * to understand the details of a particular collation strategy or
  59.  * if you need to modify that strategy.
  60.  *
  61.  * <p>
  62.  * The following example shows how to compare two strings using
  63.  * the <code>Collator</code> for the default locale.
  64.  * <blockquote>
  65.  * <pre>
  66.  * // Compare two strings in the default locale
  67.  * Collator myCollator = Collator.getInstance();
  68.  * if( myCollator.compare("abc", "ABC") < 0 )
  69.  *     System.out.println("abc is less than ABC");
  70.  * else
  71.  *     System.out.println("abc is greater than or equal to ABC");
  72.  * </pre>
  73.  * </blockquote>
  74.  *
  75.  * <p>
  76.  * You can set a <code>Collator</code>'s <em>strength</em> property
  77.  * to determine the level of difference considered significant in
  78.  * comparisons. Four strengths are provided: <code>PRIMARY</code>,
  79.  * <code>SECONDARY</code>, <code>TERTIARY</code>, and <code>IDENTICAL</code>.
  80.  * The exact assignment of strengths to language features is
  81.  * locale dependant.  For example, in Czech, "e" and "f" are considered
  82.  * primary differences, while "e" and "\u00EA" are secondary differences,
  83.  * "e" and "E" are tertiary differences and "e" and "e" are identical.
  84.  * The following shows how both case and accents could be ignored for
  85.  * US English.
  86.  * <blockquote>
  87.  * <pre>
  88.  * //Get the Collator for US English and set its strength to PRIMARY
  89.  * Collator usCollator = Collator.getInstance(Locale.US);
  90.  * usCollator.setStrength(Collator.PRIMARY);
  91.  * if( usCollator.compare("abc", "ABC") == 0 ) {
  92.  *     System.out.println("Strings are equivalent");
  93.  * }
  94.  * </pre>
  95.  * </blockquote>
  96.  * <p>
  97.  * For comparing <code>String</code>s exactly once, the <code>compare</code>
  98.  * method provides the best performance. When sorting a list of
  99.  * <code>String</code>s however, it is generally necessary to compare each
  100.  * <code>String</code> multiple times. In this case, <code>CollationKey</code>s
  101.  * provide better performance. The <code>CollationKey</code> class converts
  102.  * a <code>String</code> to a series of bits that can be compared bitwise
  103.  * against other <code>CollationKey</code>s. A <code>CollationKey</code> is
  104.  * created by a <code>Collator</code> object for a given <code>String</code>.
  105.  * <br>
  106.  * <strong>Note:</strong> <code>CollationKey</code>s from different
  107.  * <code>Collator</code>s can not be compared. See the class description
  108.  * for <a href="java.text.CollationKey.html"><code>CollationKey</code></a>
  109.  * for an example using <code>CollationKey</code>s.
  110.  *
  111.  * @see         RuleBasedCollator
  112.  * @see         CollationKey
  113.  * @see         CollationElementIterator
  114.  * @see         Locale
  115.  * @version     1.14 08/19/98
  116.  * @author      Helena Shih
  117.  */
  118.  
  119. public abstract class Collator implements Cloneable, Serializable {
  120.     /**
  121.      * Collator strength value.  When set, only PRIMARY differences are
  122.      * considered significant during comparison. The assignment of strengths
  123.      * to language features is locale dependant. A common example is for
  124.      * different base letters ("a" vs "b") to be considered a PRIMARY difference.
  125.      * @see java.text.Collator#setStrength
  126.      * @see java.text.Collator#getStrength
  127.      */
  128.     public final static int PRIMARY = 0;
  129.     /**
  130.      * Collator strength value.  When set, only SECONDARY and above differences are
  131.      * considered significant during comparison. The assignment of strengths
  132.      * to language features is locale dependant. A common example is for
  133.      * different accented forms of the same base letter ("a" vs "\u00E4") to be
  134.      * considered a SECONDARY difference.
  135.      * @see java.text.Collator#setStrength
  136.      * @see java.text.Collator#getStrength
  137.      */
  138.     public final static int SECONDARY = 1;
  139.     /**
  140.      * Collator strength value.  When set, only TERTIARY and above differences are
  141.      * considered significant during comparison. The assignment of strengths
  142.      * to language features is locale dependant. A common example is for
  143.      * case differences ("a" vs "A") to be considered a TERTIARY difference.
  144.      * @see java.text.Collator#setStrength
  145.      * @see java.text.Collator#getStrength
  146.      */
  147.     public final static int TERTIARY = 2;
  148.  
  149.     /**
  150.      * Collator strength value.  When set, all differences are
  151.      * considered significant during comparison. The assignment of strengths
  152.      * to language features is locale dependant. A common example is for control
  153.      * characters ("\u0001" vs "\u0002") to be considered equal at the
  154.      * PRIMARY, SECONDARY, and TERTIARY levels but different at the IDENTICAL
  155.      * level.  Additionally, differences between pre-composed accents such as
  156.      * "\u00C0" (A-grave) and combining accents such as "A\u0300"
  157.      * (A, combining-grave) will be considered significant at the tertiary
  158.      * level if decomposition is set to NO_DECOMPOSITION.
  159.      */
  160.     public final static int IDENTICAL = 3;
  161.  
  162.     /**
  163.      * Decomposition mode value. With NO_DECOMPOSITION
  164.      * set, accented characters will not be decomposed for collation. This
  165.      * provides the fastest collation but will only produce correct results
  166.      * for languages that do not use accents.
  167.      * @see java.text.Collator#getDecomposition
  168.      * @see java.text.Collator#setDecomposition
  169.      */
  170.     public final static int NO_DECOMPOSITION = 0;
  171.  
  172.     /**
  173.      * Decomposition mode value. With CANONICAL_DECOMPOSITION
  174.      * set, characters that are canonical variants according to Unicode 2.0
  175.      * will be decomposed for collation. This is the default setting and
  176.      * should be used to get correct collation of accented characters.
  177.      * @see java.text.Collator#getDecomposition
  178.      * @see java.text.Collator#setDecomposition
  179.      */
  180.     public final static int CANONICAL_DECOMPOSITION = 1;
  181.  
  182.     /**
  183.      * Decomposition mode value. With FULL_DECOMPOSITION
  184.      * set, both Unicode canonical variants and Unicode compatibility variants
  185.      * will be decomposed for collation.  This causes not only accented
  186.      * characters to be collated, but also characters that have special formats
  187.      * to be collated with their norminal form. For example, the half-width and
  188.      * full-width ASCII and Katakana characters are then collated together.
  189.      * FULL_DECOMPOSITION is the most complete and therefore the slowest
  190.      * decomposition mode.
  191.      * @see java.text.Collator#getDecomposition
  192.      * @see java.text.Collator#setDecomposition
  193.      */
  194.     public final static int FULL_DECOMPOSITION = 2;
  195.  
  196.     /**
  197.      * Gets the Collator for the current default locale.
  198.      * The default locale is determined by java.util.Locale.getDefault.
  199.      * @return the Collator for the default locale.(for example, en_US)
  200.      * @see java.util.Locale#getDefault
  201.      */
  202.     public static synchronized Collator getInstance() {
  203.         return getInstance(Locale.getDefault());
  204.     }
  205.  
  206.     /**
  207.      * Gets the Collator for the desired locale.
  208.      * @param desiredLocale the desired locale.
  209.      * @return the Collator for the desired locale.
  210.      * @see java.util.Locale
  211.      * @see java.util.ResourceBundle
  212.      */
  213.     public static synchronized
  214.     Collator getInstance(Locale desiredLocale)
  215.     {
  216.         RuleBasedCollator result = null;
  217.         result = (RuleBasedCollator) cache.get(desiredLocale);
  218.         if (result != null) {
  219.             return (Collator)result.clone();  // make the world safe
  220.         }
  221.  
  222.         // Load the resource of the desired locale from resource
  223.         // manager.
  224.         String colString;
  225.         try {
  226.             ResourceBundle resource = ResourceBundle.getBundle
  227.                                       ("java.text.resources.LocaleElements",
  228.                                        desiredLocale);
  229.  
  230.             colString = resource.getString("CollationElements");
  231.         } catch (MissingResourceException e) {
  232.             // return default US collation
  233.             colString = "";
  234.         }
  235.         try
  236.         {
  237.             result = new RuleBasedCollator( CollationRules.DEFAULTRULES +
  238.                                             colString );
  239.         }
  240.         catch(ParseException foo)
  241.         {
  242.             // predefined tables should contain correct grammar
  243.             try {
  244.                 result = new RuleBasedCollator( CollationRules.DEFAULTRULES );
  245.             } catch (ParseException bar) {
  246.                 // do nothing
  247.             }
  248.         }
  249.         cache.put(desiredLocale,result);
  250.         return result;
  251.     }
  252.  
  253.     /**
  254.      * Compares the source string to the target string according to the
  255.      * collation rules for this Collator.  Returns an integer less than,
  256.      * equal to or greater than zero depending on whether the source String is
  257.      * less than, equal to or greater than the target string.  See the Collator
  258.      * class description for an example of use.
  259.      * <p>
  260.      * For a one time comparison, this method has the best performance. If a
  261.      * given String will be involved in multiple comparisons, CollationKey.compareTo
  262.      * has the best performance. See the Collator class description for an example
  263.      * using CollationKeys.
  264.      * @param source the source string.
  265.      * @param target the target string.
  266.      * @return Returns an integer value. Value is less than zero if source is less than
  267.      * target, value is zero if source and target are equal, value is greater than zero
  268.      * if source is greater than target.
  269.      * @see java.text.CollationKey
  270.      * @see java.text.Collator#getCollationKey
  271.      */
  272.     public abstract int compare(String source, String target);
  273.  
  274.     /**
  275.      * Transforms the String into a series of bits that can be compared bitwise
  276.      * to other CollationKeys. CollationKeys provide better performance than
  277.      * Collator.compare when Strings are involved in multiple comparisons.
  278.      * See the Collator class description for an example using CollationKeys.
  279.      * @param source the string to be transformed into a collation key.
  280.      * @return the CollationKey for the given String based on this Collator's collation
  281.      * rules. If the source String is null, a null CollationKey is returned.
  282.      * @see java.text.CollationKey
  283.      * @see java.text.Collator#compare
  284.      */
  285.     public abstract CollationKey getCollationKey(String source);
  286.  
  287.     /**
  288.      * Convenience method for comparing the equality of two strings based on
  289.      * this Collator's collation rules.
  290.      * @param source the source string to be compared with.
  291.      * @param target the target string to be compared with.
  292.      * @return true if the strings are equal according to the collation
  293.      * rules.  false, otherwise.
  294.      * @see java.text.Collator#compare
  295.      */
  296.     public boolean equals(String source, String target)
  297.     {
  298.         return (compare(source, target) == Collator.EQUAL);
  299.     }
  300.  
  301.     /**
  302.      * Returns this Collator's strength property.  The strength property determines
  303.      * the minimum level of difference considered significant during comparison.
  304.      * See the Collator class description for an example of use.
  305.      * @return this Collator's current strength property.
  306.      * @see java.text.Collator#setStrength
  307.      * @see java.text.Collator#PRIMARY
  308.      * @see java.text.Collator#SECONDARY
  309.      * @see java.text.Collator#TERTIARY
  310.      * @see java.text.Collator#IDENTICAL
  311.      */
  312.     public synchronized int getStrength()
  313.     {
  314.         return strength;
  315.     }
  316.  
  317.     /**
  318.      * Sets this Collator's strength property.  The strength property determines
  319.      * the minimum level of difference considered significant during comparison.
  320.      * See the Collator class description for an example of use.
  321.      * @param the new strength value.
  322.      * @see java.text.Collator#getStrength
  323.      * @see java.text.Collator#PRIMARY
  324.      * @see java.text.Collator#SECONDARY
  325.      * @see java.text.Collator#TERTIARY
  326.      * @see java.text.Collator#IDENTICAL
  327.      * @exception  IllegalArgumentException If the new strength value is not one of
  328.      * PRIMARY, SECONDARY, TERTIARY or IDENTICAL.
  329.      */
  330.     public synchronized void setStrength(int newStrength) {
  331.         if ((newStrength != PRIMARY) &&
  332.             (newStrength != SECONDARY) &&
  333.             (newStrength != TERTIARY) &&
  334.             (newStrength != IDENTICAL))
  335.             throw new IllegalArgumentException("Incorrect comparison level.");
  336.         strength = newStrength;
  337.     }
  338.  
  339.     /**
  340.      * Get the decomposition mode of this Collator. Decomposition mode
  341.      * determines how Unicode composed characters are handled. Adjusting
  342.      * decomposition mode allows the user to select between faster and more
  343.      * complete collation behavior.
  344.      * <p>The three values for decomposition mode are:
  345.      * <UL>
  346.      * <LI>NO_DECOMPOSITION,
  347.      * <LI>CANONICAL_DECOMPOSITION
  348.      * <LI>FULL_DECOMPOSITION.
  349.      * </UL>
  350.      * See the documentation for these three constants for a description
  351.      * of their meaning.
  352.      * @return the decomposition mode
  353.      * @see java.text.Collator#setDecomposition
  354.      * @see java.text.Collator#NO_DECOMPOSITION
  355.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  356.      * @see java.text.Collator#FULL_DECOMPOSITION
  357.      */
  358.     public synchronized int getDecomposition()
  359.     {
  360.         return decmp;
  361.     }
  362.     /**
  363.      * Set the decomposition mode of this Collator. See getDecomposition
  364.      * for a description of decomposition mode.
  365.      * @param the new decomposition mode
  366.      * @see java.text.Collator#getDecomposition
  367.      * @see java.text.Collator#NO_DECOMPOSITION
  368.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  369.      * @see java.text.Collator#FULL_DECOMPOSITION
  370.      * @exception IllegalArgumentException If the given value is not a valid decomposition
  371.      * mode.
  372.      */
  373.     public synchronized void setDecomposition(int decompositionMode) {
  374.         if ((decompositionMode != NO_DECOMPOSITION) &&
  375.             (decompositionMode != CANONICAL_DECOMPOSITION) &&
  376.             (decompositionMode != FULL_DECOMPOSITION))
  377.             throw new IllegalArgumentException("Wrong decomposition mode.");
  378.         decmp = decompositionMode;
  379.     }
  380.  
  381.     /**
  382.      * Get the set of Locales for which Collators are installed.
  383.      * @return the list of available locales which collators are installed.
  384.      */
  385.     public static synchronized Locale[] getAvailableLocales() {
  386.         return LocaleData.getAvailableLocales("CollationElements");
  387.     }
  388.  
  389.     /**
  390.      * Overrides Cloneable
  391.      */
  392.     public Object clone()
  393.     {
  394.         try {
  395.             return (Collator)super.clone();
  396.         } catch (CloneNotSupportedException e) {
  397.             throw new InternalError();
  398.         }
  399.     }
  400.  
  401.     /**
  402.      * Compares the equality of two Collators.
  403.      * @param that the Collator to be compared with this.
  404.      * @return true if this Collator is the same as that Collator;
  405.      * false otherwise.
  406.      */
  407.     public boolean equals(Object that)
  408.     {
  409.         if (this == that) return true;
  410.         if (that == null) return false;
  411.         if (getClass() != that.getClass()) return false;
  412.         Collator other = (Collator) that;
  413.         return ((strength == other.strength) &&
  414.                 (decmp == other.decmp));
  415.     }
  416.  
  417.     /**
  418.      * Generates the hash code for this Collator.
  419.      */
  420.     abstract public int hashCode();
  421.  
  422.     /**
  423.      * Default constructor.  This constructor is
  424.      * protected so subclasses can get access to it. Users typically create
  425.      * a Collator sub-class by calling the factory method getInstance.
  426.      * @see java.text.Collator#getInstance
  427.      */
  428.     protected Collator()
  429.     {
  430.         strength = TERTIARY;
  431.         decmp = CANONICAL_DECOMPOSITION;
  432.     }
  433.  
  434.     private int strength = 0;
  435.     private int decmp = 0;
  436.     private static Hashtable cache = new Hashtable();
  437.  
  438.     //
  439.     // FIXME: These three constants should be removed.
  440.     //
  441.     /**
  442.      * LESS is returned if source string is compared to be less than target
  443.      * string in the compare() method.
  444.      * @see java.text.Collator#compare
  445.      */
  446.     final static int LESS = -1;
  447.     /**
  448.      * EQUAL is returned if source string is compared to be equal to target
  449.      * string in the compare() method.
  450.      * @see java.text.Collator#compare
  451.      */
  452.     final static int EQUAL = 0;
  453.     /**
  454.      * GREATER is returned if source string is compared to be greater than
  455.      * target string in the compare() method.
  456.      * @see java.text.Collator#compare
  457.      */
  458.     final static int GREATER = 1;
  459.  
  460.     // Proclaims serialization compatibility to 1.1.
  461.     static final long serialVersionUID = -7718728969026499504L;
  462.  }
  463.